public class Multithreading {
    public static void main(String[] args) {
        System.out.println("=== Java 多线程编程示例 ===\n");
        
        // 8.1 线程基础示例
        demonstrateThreadBasics();
        
        // 8.2 线程同步示例
        demonstrateThreadSynchronization();
        
        // 8.3 线程池示例
        demonstrateThreadPool();
        
        // 8.4 并发工具类示例
        demonstrateConcurrencyUtilities();
    }
    
    // 8.1 线程基础示例
    public static void demonstrateThreadBasics() {
        System.out.println("=== 8.1 线程基础 ===");
        
        // 通过继承 Thread 类创建线程
        MyThread myThread = new MyThread();
        myThread.start();
        
        // 通过实现 Runnable 接口创建线程
        Thread runnableThread = new Thread(new MyRunnable());
        runnableThread.start();
        
        // 等待线程执行完毕
        try {
            myThread.join();
            runnableThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println();
    }
    
    // 8.2 线程同步示例
    public static void demonstrateThreadSynchronization() {
        System.out.println("=== 8.2 线程同步 ===");
        
        // synchronized 关键字示例
        Counter counter = new Counter();
        
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        t1.start();
        t2.start();
        
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("计数器最终值（使用 synchronized）: " + counter.getCount());
        
        // volatile 关键字示例
        SharedFlag sharedFlag = new SharedFlag();
        
        Thread writer = new Thread(() -> {
            try {
                Thread.sleep(1000);
                sharedFlag.setFlag(true);
                System.out.println("标志已设置为 true");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        
        Thread reader = new Thread(() -> {
            while (!sharedFlag.getFlag()) {
                // 等待标志变为 true
            }
            System.out.println("检测到标志变为 true");
        });
        
        reader.start();
        writer.start();
        
        try {
            reader.join();
            writer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // Lock 接口示例
        LockCounter lockCounter = new LockCounter();
        
        Thread lt1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                lockCounter.increment();
            }
        });
        
        Thread lt2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                lockCounter.increment();
            }
        });
        
        lt1.start();
        lt2.start();
        
        try {
            lt1.join();
            lt2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("计数器最终值（使用 Lock）: " + lockCounter.getCount());
        
        System.out.println();
    }
    
    // 8.3 线程池示例
    public static void demonstrateThreadPool() {
        System.out.println("=== 8.3 线程池 ===");
        
        // 使用 Executors 工具类创建线程池
        java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newFixedThreadPool(2);
        
        // 提交任务到线程池
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("任务 " + taskId + " 正在执行，线程: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务 " + taskId + " 执行完毕");
            });
        }
        
        // 关闭线程池
        executor.shutdown();
        
        try {
            // 等待所有任务完成
            if (!executor.awaitTermination(10, java.util.concurrent.TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
        }
        
        System.out.println();
    }
    
    // 8.4 并发工具类示例
    public static void demonstrateConcurrencyUtilities() {
        System.out.println("=== 8.4 并发工具类 ===");
        
        // CountDownLatch 示例
        System.out.println("CountDownLatch 示例:");
        java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(3);
        
        for (int i = 0; i < 3; i++) {
            final int workerId = i;
            new Thread(() -> {
                System.out.println("工作线程 " + workerId + " 正在执行任务");
                try {
                    Thread.sleep((workerId + 1) * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("工作线程 " + workerId + " 完成任务");
                latch.countDown();
            }).start();
        }
        
        try {
            System.out.println("主线程等待所有工作线程完成...");
            latch.await();
            System.out.println("所有工作线程已完成，主线程继续执行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // Semaphore 示例
        System.out.println("\nSemaphore 示例:");
        java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(2); // 只允许2个线程同时访问
        
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println("任务 " + taskId + " 获得许可，正在执行");
                    Thread.sleep(2000);
                    System.out.println("任务 " + taskId + " 执行完毕，释放许可");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        
        // 给足够的时间让所有线程执行
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println();
    }
}

// 8.1 线程基础 - 通过继承 Thread 类创建线程
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("通过继承 Thread 类创建的线程正在执行: " + Thread.currentThread().getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("通过继承 Thread 类创建的线程执行完毕: " + Thread.currentThread().getName());
    }
}

// 8.1 线程基础 - 通过实现 Runnable 接口创建线程
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("通过实现 Runnable 接口创建的线程正在执行: " + Thread.currentThread().getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("通过实现 Runnable 接口创建的线程执行完毕: " + Thread.currentThread().getName());
    }
}

// 8.2 线程同步 - synchronized 关键字
class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}

// 8.2 线程同步 - volatile 关键字
class SharedFlag {
    private volatile boolean flag = false;
    
    public boolean getFlag() {
        return flag;
    }
    
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

// 8.2 线程同步 - Lock 接口
class LockCounter {
    private int count = 0;
    private final java.util.concurrent.locks.Lock lock = new java.util.concurrent.locks.ReentrantLock();
    
    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
    
    public int getCount() {
        return count;
    }
}